From 9f03682258d949b3b6ddd4fedec93977dedbadde Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Thu, 29 May 2014 13:34:38 +0200 Subject: Enderman attacks a player if he's looking at him. --- src/Mobs/Enderman.cpp | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/Mobs/Enderman.h | 1 + 2 files changed, 91 insertions(+) diff --git a/src/Mobs/Enderman.cpp b/src/Mobs/Enderman.cpp index becc99a86..bd5ed85f1 100644 --- a/src/Mobs/Enderman.cpp +++ b/src/Mobs/Enderman.cpp @@ -2,6 +2,66 @@ #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules #include "Enderman.h" +#include "../Entities/Player.h" + + + + +/////////////////////////////////////////////////////////////////////////// +// cPlayerLookCheck +class cPlayerLookCheck : + public cPlayerListCallback +{ +public: + cPlayerLookCheck(Vector3d a_EndermanPos) : + m_EndermanPos(a_EndermanPos), + m_Player(NULL) + { + } + + virtual bool Item(cPlayer * a_Player) override + { + // Don't check players who are in creative gamemode. + if (a_Player->IsGameModeCreative()) + { + return false; + } + + Vector3d Direction = m_EndermanPos - a_Player->GetPosition(); + + // Don't check players who are more then 64 blocks away. + if (Direction.SqrLength() > 64) + { + return false; + } + + // Don't check if the player has a pumpkin on his head. + if (a_Player->GetEquippedHelmet().m_ItemType == E_BLOCK_PUMPKIN) + { + return false; + } + + Direction.Normalize(); + + Vector3d LookVector = a_Player->GetLookVector(); + LookVector.Normalize(); + + if ((Direction - LookVector).SqrLength() > 0.02) + { + return false; + } + + // TODO: Don't attack the player if there is a wall between the player and the enderman. + m_Player = a_Player; + return true; + } + + cPlayer * GetPlayer(void) const {return m_Player;} + bool HasFoundPlayer(void) const {return (m_Player != NULL);} +protected: + cPlayer * m_Player; + Vector3d m_EndermanPos; +} ; @@ -32,3 +92,33 @@ void cEnderman::GetDrops(cItems & a_Drops, cEntity * a_Killer) +void cEnderman::Tick(float a_Dt, cChunk & a_Chunk) +{ + super::Tick(a_Dt, a_Chunk); + + if (m_Target != NULL) + { + return; + } + + cPlayerLookCheck Callback(GetPosition()); + if (!m_World->ForEachPlayer(Callback)) + { + return; + } + + if (!Callback.HasFoundPlayer()) + { + return; + } + + m_bIsScreaming = true; + m_Target = Callback.GetPlayer(); + + m_World->BroadcastEntityMetadata(*this); +} + + + + + diff --git a/src/Mobs/Enderman.h b/src/Mobs/Enderman.h index 32e40e70b..be6e7bdf4 100644 --- a/src/Mobs/Enderman.h +++ b/src/Mobs/Enderman.h @@ -18,6 +18,7 @@ public: CLASS_PROTODEF(cEnderman); virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override; + virtual void Tick(float a_Dt, cChunk & a_Chunk) override; bool IsScreaming(void) const {return m_bIsScreaming; } BLOCKTYPE GetCarriedBlock(void) const {return CarriedBlock; } -- cgit v1.2.3